import { StreamCollector } from "@smithy/types";

import { Collector } from "./collector";
import { buffer, stream, util } from "@kit.ArkTS";
import hilog from "@ohos.hilog";

/**
 * @internal
 * Converts a stream to a byte array.
 */
export const streamCollector: StreamCollector = (inputStream: stream.Readable | string): Promise<Uint8Array> => {
  return new Promise((resolve, reject) => {
    if (typeof inputStream === 'string') {
      resolve(new Uint8Array(buffer.from(inputStream).buffer))
    } else {
      const chunks: Uint8Array[] = [];
      inputStream.on('data', (data) => {
        if (typeof data.data === 'string') {
          const chunk = stringToBuffer(data.data)
          chunks.push(chunk)
        }
        if (data.data instanceof Uint8Array) {
          chunks.push(data.data);
        }
      });

      inputStream.on('end', () => {
        if(chunks.length>0){
          const result = new Uint8Array(buffer.concat(chunks).buffer);
          resolve(result);
        }else{
          reject(new Error('streamCollector:inputStream has no data'));
        }
      });
      const writeable = new stream.Writable()
      inputStream.on('error', (err) => {
        reject(new Error('streamCollector:inputStream error'));
        writeable.end()
      });
      inputStream.pipe(new stream.Writable())
    }
  });
};

const stringToBuffer = (input: string, encoding?: string) => {
  if (encoding && buffer.isEncoding(encoding)) {
    return new Uint8Array(buffer.from(input, encoding as buffer.BufferEncoding).buffer)
  } else {
    return new Uint8Array(buffer.from(input).buffer)
  }
}

/**
 * Note: the global.ReadableStream object is marked experimental, and was added in v18.0.0 of Node.js.
 * The importable version was added in v16.5.0. We only test for the global version so as not to
 * enforce an import on a Node.js version that may not have it, and import
 * only the type from stream/web.
 */
// const isReadableStreamInstance = (stream: unknown): stream is IReadableStream =>
//   typeof ReadableStream === "function" && stream instanceof ReadableStream;
//
// async function collectReadableStream(stream: IReadableStream): Promise<Uint8Array> {
//   const chunks = [];
//   const reader = stream.getReader();
//   let isDone = false;
//   let length = 0;
//
//   while (!isDone) {
//     const { done, value } = await reader.read();
//     if (value) {
//       chunks.push(value);
//       length += value.length;
//     }
//     isDone = done;
//   }
//
//   const collected = new Uint8Array(length);
//   let offset = 0;
//   for (const chunk of chunks) {
//     collected.set(chunk, offset);
//     offset += chunk.length;
//   }
//
//   return collected;
// }
export * from './collector'

export * from './readable.mock'